﻿using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using blog.Model.Oo;
using Microsoft.IdentityModel.Tokens;

namespace blog.web.Middlewares;

public class JwtMiddleware
{
        private readonly RequestDelegate _next;
        private readonly JwtOpt _authOptions;

        public JwtMiddleware(RequestDelegate next, IConfiguration configuration)
        {
            _next = next;
            _authOptions = configuration.GetSection("JwtOpt").Get<JwtOpt>();
        }

        public async Task Invoke(HttpContext context)
        {
            var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last()
                        ?? context.Request.Headers["token"].FirstOrDefault()
                        ?? context.Request.Query["Token"].FirstOrDefault()
                        ?? context.Request.Cookies["Token"];
            if (token != null)
                AttachUserToContext(context, token);
            await _next(context);
        }

        private void AttachUserToContext(HttpContext context, string token)
        {
            try
            {
                var tokenHandler = new JwtSecurityTokenHandler();
                byte[]? key = Encoding.ASCII.GetBytes(_authOptions.SecurityKey);
                tokenHandler.ValidateToken(token, new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidIssuer = _authOptions.Issuer,
                    ValidAudience = _authOptions.Audience,
                    ClockSkew = TimeSpan.Zero
                }, out SecurityToken validatedToken);
                var jwtToken = (JwtSecurityToken)validatedToken;
                var user = jwtToken.Claims.First(x => x.Type == "userid").Value;
                var claimsIdentity = new ClaimsIdentity(new Claim[] { new Claim("userid", jwtToken.Claims.First(x => x.Type == "userid").Value) });
                Thread.CurrentPrincipal = new ClaimsPrincipal(claimsIdentity);
                context.Items["User"] = user;
            }
            catch
            {
                
            }
        }
}